package com.byx.spinneredittext;

import android.annotation.SuppressLint;
import android.content.Context;
import android.content.res.ColorStateList;
import android.content.res.TypedArray;
import android.graphics.drawable.Drawable;
import android.os.Build;
import android.text.Editable;
import android.text.TextUtils;
import android.text.TextWatcher;
import android.util.AttributeSet;
import android.util.TypedValue;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.inputmethod.EditorInfo;
import android.widget.AdapterView;
import android.widget.BaseAdapter;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.TextView;

import androidx.annotation.Nullable;
import androidx.annotation.RequiresApi;

import java.lang.reflect.Field;

/**
 * SpinnerEditText
 *
 * @author Superb
 * @date 2021/1/30 11:07
 */
public class DropdownEditText extends LinearLayout {
    private EditText editText;
    private ImageView clearButton;
    private ImageView dropDownButton;
    private PopupWindow popupWindow;
    private int xoff;
    private int yoff;
    private View anchor;

    private OnDropDownClickedListener onDropDownClickedListener;
    private AdapterView.OnItemClickListener onItemClickListener;

    private OnDropDownClickedListener defaultOnDropDownClickedListener;

    @RequiresApi(api = Build.VERSION_CODES.Q)
    public DropdownEditText(Context context) {
        super(context);
        init(context,null);
    }

    @RequiresApi(api = Build.VERSION_CODES.Q)
    public DropdownEditText(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        init(context,attrs);
    }

    @RequiresApi(api = Build.VERSION_CODES.Q)
    public DropdownEditText(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init(context,attrs);
    }

    @RequiresApi(api = Build.VERSION_CODES.Q)
    public DropdownEditText(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);
        init(context,attrs);
    }

    @RequiresApi(api = Build.VERSION_CODES.Q)
    private void init(final Context context, @Nullable AttributeSet attrs){
        LayoutInflater.from(context).inflate(R.layout.spinner_edit_text_layout_main, this, true);
        editText=findViewById(R.id.editText);
        clearButton=findViewById(R.id.clear);
        dropDownButton=findViewById(R.id.dropdown);
        popupWindow=new PopupWindow(context);
        anchor=this;

        if(null != attrs){
            TypedArray attributes = context.obtainStyledAttributes(attrs, R.styleable.DropdownEditText);
            CharSequence charSequence=attributes.getText(R.styleable.DropdownEditText_dd_hint);
            if(null != charSequence){
                editText.setHint(charSequence);
            }
            editText.setEms(attributes.getInt(R.styleable.DropdownEditText_dd_ems,-1));
            editText.setInputType(attributes.getInt(R.styleable.DropdownEditText_dd_inputType,EditorInfo.TYPE_NULL));
            Drawable background=attributes.getDrawable(R.styleable.DropdownEditText_dd_editTextBackground);
            if(null != background){
                editText.setBackground(background);
            }
            CharSequence text=attributes.getText(R.styleable.DropdownEditText_dd_text);
            if(null != text){
                editText.setText(text);
            }

            editText.setTextSize(TypedValue.COMPLEX_UNIT_PX,attributes.getDimension(R.styleable.DropdownEditText_dd_textSize,18));
            ColorStateList colorStateList=attributes.getColorStateList(R.styleable.DropdownEditText_dd_textColor);
            if(null != colorStateList){
                editText.setTextColor(colorStateList);
            }
            int drawable=attributes.getResourceId(R.styleable.DropdownEditText_dd_editTextCursorBackground,0);
//        editText.setTextCursorDrawable(drawable);
            if(drawable != 0){
                try {
                    Field setCursor = TextView.class.getDeclaredField("mCursorDrawableRes");
                    setCursor.setAccessible(true);
                    setCursor.set(editText,drawable);
                } catch (NoSuchFieldException | IllegalAccessException e) {
                    e.printStackTrace();
                }
            }
            clearButton.setImageResource(attributes.getResourceId(R.styleable.DropdownEditText_dd_clearButtonIcon,R.mipmap.ic_clear_input));
            xoff=attributes.getDimensionPixelOffset(R.styleable.DropdownEditText_dd_dropDownHorizontalOffset,0);
            yoff=attributes.getDimensionPixelOffset(R.styleable.DropdownEditText_dd_dropDownVerticalOffset,0);
            attributes.recycle();
        }

        editText.addTextChangedListener(new TextWatcher() {
            @Override
            public void beforeTextChanged(CharSequence s, int start, int count, int after) {

            }

            @Override
            public void onTextChanged(CharSequence s, int start, int before, int count) {
                clearButton.setVisibility(TextUtils.isEmpty(s) ? View.GONE : View.VISIBLE);
            }

            @Override
            public void afterTextChanged(Editable s) {

            }
        });

        clearButton.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                editText.getText().clear();
            }
        });

        defaultOnDropDownClickedListener=new OnDropDownClickedListener() {
            @SuppressLint("UseCompatLoadingForDrawables")
            @Override
            public void onDropDownClick(View v, final android.widget.PopupWindow popupWindow) {
                if(popupWindow != null){
                    popupWindow.setWidth(anchor.getWidth());
                    popupWindow.setOutsideTouchable(true);
                    popupWindow.setFocusable(true);
                    popupWindow.setTouchInterceptor(new View.OnTouchListener() {
                        @SuppressLint("ClickableViewAccessibility")
                        @Override
                        public boolean onTouch(View v, MotionEvent event) {
                            if(event.getAction() == MotionEvent.ACTION_OUTSIDE){
                                popupWindow.dismiss();
                                return true;
                            }
                            return false;
                        }
                    });
                    popupWindow.showAsDropDown(anchor,xoff,yoff);
                    dropDownButton.setImageDrawable(context.getDrawable(R.mipmap.ic_spinner_up));
                }
            }
        };

        dropDownButton.setOnClickListener(new OnClickListener() {
            /**
             * Called when a view has been clicked.
             *
             * @param v The view that was clicked.
             */
            @Override
            public void onClick(View v) {
                if(null == onDropDownClickedListener){
                    defaultOnDropDownClickedListener.onDropDownClick(v,popupWindow);
                } else{
                    onDropDownClickedListener.onDropDownClick(v,popupWindow);
                }
            }
        });

        popupWindow.setOnDismissListener(new PopupWindow.OnDismissListener() {
            @SuppressLint("UseCompatLoadingForDrawables")
            @Override
            public void onDismiss() {
                dropDownButton.setImageDrawable(context.getDrawable(R.mipmap.ic_spinner_down));
            }
        });
        popupWindow.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                onItemClickListener.onItemClick(parent,view,position,id);

            }
        });
    }

    public EditText getEditText() {
        return editText;
    }

    public ImageView getClearButton() {
        return clearButton;
    }

    public ImageView getDropDownButton() {
        return dropDownButton;
    }

    public void setText(CharSequence charSequence){
        editText.setText(charSequence);
    }

    public void setTextSize(float size){
        editText.setTextSize(size);
    }

    public void setTextColor(int color){
        editText.setTextColor(color);
    }

    public void setPopupWindow(PopupWindow popupWindow) {
        this.popupWindow = popupWindow;
    }

    public void setOnDropDownClickedListener(OnDropDownClickedListener onDropDownClickedListener) {
        this.onDropDownClickedListener = onDropDownClickedListener;
    }

    public void setOnItemClickListener(AdapterView.OnItemClickListener onItemClickListener) {
        this.onItemClickListener = onItemClickListener;
    }

    public void setPopupWindowOffset(int xoff, int yoff){
        this.xoff=xoff;
        this.yoff=yoff;
    }

    public void setPopupWindowBackgroundDrawable(Drawable backgroundDrawable){
        this.popupWindow.setBackgroundDrawable(backgroundDrawable);
    }

    public void setAnchor(View anchor) {
        this.anchor = anchor;
    }

    public void setAdapter(BaseAdapter adapter){
        if(null != adapter && !adapter.isEmpty()){
            this.popupWindow.setAdapter(adapter);
            dropDownButton.setVisibility(VISIBLE);
        }else {
            dropDownButton.setVisibility(GONE);
        }
    }

    /**
     * 下拉按钮点击事件监听器
     */
    interface OnDropDownClickedListener{
        /**
         * 点击下拉框时回调
         * @param v
         * @param popupWindow 下拉界面
         */
        void onDropDownClick(View v, android.widget.PopupWindow popupWindow);
    }

    /**
     * PopupWindow
     *
     * @author Superb
     * @date 2021/1/30 11:13
     */
    private static class PopupWindow extends android.widget.PopupWindow {
        protected ListView listView;
        private AdapterView.OnItemClickListener onItemClickListener;

        /**
         * <p>Create a new empty, non focusable popup window of dimension (0,0).</p>
         *
         * <p>The popup does provide a background.</p>
         *
         * @param context
         */
        public PopupWindow(Context context) {
            super(context);
            @SuppressLint("InflateParams")
            View view = LayoutInflater.from(context).inflate(R.layout.spinner_edit_text_layout_popup_window, null);
            setContentView(view);
            setWidth(ViewGroup.LayoutParams.WRAP_CONTENT);
            setHeight(ViewGroup.LayoutParams.WRAP_CONTENT);
            listView=view.findViewById(R.id.listView);
            listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
                @Override
                public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                dismiss();
                if(null != onItemClickListener){
                    onItemClickListener.onItemClick(parent,view,position,id);
                }
                }
            });
        }

        public void setAdapter(BaseAdapter adapter) {
            listView.setAdapter(adapter);
        }

        public void setOnItemClickListener(AdapterView.OnItemClickListener onItemClickListener) {
            this.onItemClickListener = onItemClickListener;
        }
    }
}
